Springboot+JWT+Vue实现登录功能

您所在的位置:网站首页 springboot jwt 单点登录 Springboot+JWT+Vue实现登录功能

Springboot+JWT+Vue实现登录功能

2023-09-04 18:26| 来源: 网络整理| 查看: 265

一、前言

最近在写一个Springboot+Vue的前后端分离项目,并且刚学了JWT的功能和原理,正好拿来练练手,在开发过程中也遇到了很多坑点,主要是对vue和springboot不够熟练导致的,因此写篇文章来记录分享。

二、JWT1.介绍

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。

2.请求流程

1. 用户使用账号发出请求; 2. 服务器使用私钥创建一个jwt; 3. 服务器返回这个jwt给浏览器; 4. 浏览器将该jwt串在请求头中像服务器发送请求; 5. 服务器验证该jwt; 6. 返回响应的资源给浏览器。

3.JWT的主要应用场景

身份认证在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录(SSO)中比较广泛的使用了该技术。 信息交换在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。

4.JWT的结构

JWT包含了三部分:

Header 头部(标题包含了令牌的元数据,并且包含签名和/或加密算法的类型)

Payload 负载 (类似于飞机上承载的物品,存放我们指定的信息)

Signature 签名/签证

将这三段信息文本用.连接一起就构成了JWT字符串。

就像这样: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

三、Springboot集成JWT1. Maven添加JWT依赖项 com.auth0 java-jwt 3.4.0 2. 封装Token的生成函数 public String getToken(User user, long time) { Date start = new Date();//token起始时间 long currentTime = System.currentTimeMillis() + time; Date end = new Date(currentTime);//token结束时间 String token = ""; token = JWT.create() .withAudience(user.getLevel().toString()+user.getId().toString()) //存放接收方的信息 .withIssuedAt(start)//token开始时间 .withExpiresAt(end)//token存活截止时间 .sign(Algorithm.HMAC256(user.getPassword()));//加密 return token; }3. 编写注解类

1.UserLoginToken 需要登录才能进行操作的注解

@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface UserLoginToken { boolean required() default true; }

2.PassToken 用来跳过验证的

@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface PassToken { boolean required() default true; }4. 编写权限拦截器(AuthenticationInterceptor)@Slf4j public class AuthenticationInterceptor implements HandlerInterceptor { @Autowired UserService userService; @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception { //通过所有OPTION请求 if(httpServletRequest.getMethod().toUpperCase().equals("OPTIONS")){ return true; } String token = httpServletRequest.getHeader("Authorization");// 从 http 请求头中取出 token String refreshToken = httpServletRequest.getHeader("freshToken");// 从 http 请求头中取出 token // 如果该请求不是映射到方法直接通过 if (!(object instanceof HandlerMethod)) { return true; } HandlerMethod handlerMethod = (HandlerMethod) object; Method method = handlerMethod.getMethod(); //检查是否有passtoken注释,有则跳过认证 if (method.isAnnotationPresent(PassToken.class)) { PassToken passToken = method.getAnnotation(PassToken.class); if (passToken.required()) { return true; } } // 获取 token 中的 用户信息 String userValue = null; try { userValue = JWT.decode(token).getAudience().get(0); } catch (JWTDecodeException j) { throw new RuntimeException("401"); } Map map = new HashMap(); map.put("level", (userValue).substring(0,1)); map.put("id", (userValue).substring(1)); User user = userService.findUser(map); if (user == null) { throw new RuntimeException("用户不存在,请重新登录"); } Date oldTime = JWT.decode(token).getExpiresAt(); Date refreshTime = JWT.decode(refreshToken).getExpiresAt(); long oldDiff = oldTime.getTime() - new Date().getTime();//这样得到的差值是毫秒级别 long refreshDiff = refreshTime.getTime() - new Date().getTime();//这样得到的差值是毫秒级别 if (oldDiff { //请求错误处理 // loadingInstance.close() Message.error({ message: '加载超时' }); return Promise.reject(error); }); // var count = 0; axios.interceptors.response.use(response => { return response; }, error => { if (error.response.status === 401) { if (count === 0) { count = count + 1; } else if (count > 0) { return null; } // debugger Message.error("身份信息超时,请重新登录!", { icon: 1, time: 2000 }); $cookies.remove('userToken'); setTimeout(function () { window.location.href = '/#/login'; }, 3000); return Promise.reject(error); } } ); export default axios; //暴露axios实例

然后在main.js中配置

import axiosHelper from '../src/axios/axiosHelper' Vue.prototype.axiosHelper = axiosHelper;2. axios接收Token, 并放入localStorage中

只需在拿到后端数据data后, 添加以下代码

let obj = { username: data.username, level: data.level } localStorage.setItem('userToken', data.token) localStorage.setItem('refreshToken', data.refreshToken)五、总结

至此,我们就配置好了前后端的JWT使用环境,之后还会继续更新我在学习技术时总结的干货,希望大家多多点赞支持哦!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3